package cc.eddic.practice.concurrency.impl;

import cc.eddic.practice.concurrency.ExecutorServiceUtil;
import cc.eddic.practice.concurrency.LogItem;
import cc.eddic.practice.concurrency.LogParser;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;


public class LogParserWithExecutorVer1ScwImpl implements LogParser {

    private static final int LOG_FILE_COUNT = 256;


    @Override
    public Map<String, List<LogItem>> parse(String folderName) {
        Map<String, List<LogItem>> resultMap = new ConcurrentHashMap<>();
        ExecutorService executorService = Executors.newFixedThreadPool(128);
        CountDownLatch latch = new CountDownLatch(LOG_FILE_COUNT);

        traverseFolder(new File(folderName),resultMap,executorService,latch);

        try {
            latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            executorService.shutdown();
        }
        return resultMap;
    }

    private void parseLogFile(String path,Map<String, List<LogItem>> resultMap,CountDownLatch latch) throws IOException {
        List<LogItem> logItems = new ArrayList<>();
        LogItemParserScwImpl logItemParser = new LogItemParserScwImpl();
        try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
            String line;
            while ((line = reader.readLine()) != null) {
                Optional<LogItem> parsedLogItem = logItemParser.parse(line);
                parsedLogItem.ifPresent(logItems::add);
            }
            resultMap.put(path,logItems);

        }finally {
            latch.countDown();
        }
    }

    private void traverseFolder(File fileFolder, Map<String, List<LogItem>> resultMap,ExecutorService executorService,CountDownLatch latch) {
        File[] files = fileFolder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    traverseFolder(file, resultMap,executorService,latch);
                } else if (file.getName().endsWith(".log")) {
                   executorService.submit(() -> {
                       try {
                           parseLogFile(file.getAbsolutePath(),resultMap,latch);
                       } catch (IOException e) {
                           throw new RuntimeException(e);
                       }
                   });
                }
            }
        }
    }
}


